
package com.be.beadmin.basicData.impl;

import com.alibaba.druid.util.StringUtils;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.be.beadmin.basicData.dto.input.OrgParentFilter;
import com.be.beadmin.basicData.entity.Menu;
import com.be.beadmin.basicData.entity.Menu_;
import com.be.beadmin.basicData.entity.Organization;
import com.be.beadmin.basicData.entity.Organization_;
import cn.hutool.core.util.ObjectUtil;
import com.be.beadmin.common.entity.PageEntity;
import com.be.beadmin.common.exception.BeadminException;
import com.be.beadmin.common.utils.JpaQueryBuilder;
import com.be.beadmin.common.utils.JpaSortBuilder;
import lombok.RequiredArgsConstructor;
import com.be.beadmin.basicData.mapper.OrganizationMapperEx;
import com.be.beadmin.basicData.repository.OrganizationRepository;
import com.be.beadmin.basicData.service.OrganizationService;
import com.be.beadmin.basicData.dto.input.OrganizationDto;
import com.be.beadmin.basicData.dto.output.OrganizationEx;
import com.be.beadmin.basicData.dto.input.OrganizationQueryCriteria;
import com.be.beadmin.basicData.mapper.OrganizationMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Order;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;

/**
* @description 服务实现
* @author chenwei
* @date 2023-04-18
**/
@Service
@RequiredArgsConstructor
public class OrganizationServiceImpl implements OrganizationService {



    public String MENU_TITLE = "title";

    public String MENU_KEY = "key";


    public String MENU_VALUE = "value";

    public String MENU_CHILDREN = "children";

    @Autowired
    private  OrganizationRepository organizationRepository;
    @Autowired
    private  OrganizationMapper organizationMapper;
    @Autowired
    private  OrganizationMapperEx organizationExMapper;

    @Override
    public Page<OrganizationEx> getOrganizationByPage(OrgParentFilter pageEntity) {
            Pageable pageable = PageRequest.of(
            pageEntity.getCurrent() -1,
            pageEntity.getPageSize());
            Page<Organization> page = organizationRepository.findAll((root, criteriaQuery, criteriaBuilder) -> {
                    List<Predicate> list = new ArrayList<>();
                    Predicate pre1 =   JpaQueryBuilder.getPredicate(root, pageEntity.getFilters(), criteriaBuilder);
                    list.add(pre1);
                    Predicate pre2 = criteriaBuilder.equal(root.get(Organization_.delete), 0); //过滤为0
                    list.add(pre2);
                     if (!StringUtils.isEmpty(pageEntity.getParentId())) {
                         // 级联查询
                         Predicate pre3 = criteriaBuilder.equal(root.get(Organization_.parentOrg).get(Menu_.id), pageEntity.getParentId()); //过滤为0
                         list.add(pre3);
                     }
                    Predicate[] p = new Predicate[list.size()];
                    List<Order> orders = new ArrayList<>();
                    if(pageEntity.getSorters() != null && pageEntity.getSorters().size() > 0) {
                        orders = JpaSortBuilder.getPredicate(root, pageEntity.getSorters(), criteriaBuilder);
                        criteriaQuery.orderBy(orders);
                    } else {
                        criteriaQuery.orderBy(criteriaBuilder.desc(root.get(Organization_.createTime).as(Date.class)));
                    }
                    return  criteriaBuilder.and(list.toArray(p));
                    }
                    , pageable);
            Page<OrganizationEx> page1 = page.map(organizationExMapper::toEntity);
            return page1;

    }

    @Override
    public void addOrganization(OrganizationDto organizationDto) {
            Organization result = organizationRepository.findByOrgCodeAndDelete(organizationDto.getOrgCode(), 0);
            if(ObjectUtil.isNotEmpty(result)) {
                throw new BeadminException("该编码已经存在不要重复提交");
            }
            Organization parent = organizationRepository.findOrganizationById(organizationDto.getParentId());
            Organization organization = organizationMapper.toEntity(organizationDto);
            organization.setParentOrg(parent);
            organizationRepository.save(organization);
    }

    @Override
    public void updateOrganization(OrganizationDto organizationDto) {
            Organization organization = organizationRepository.findOrganizationById(organizationDto.getId());
            organization = organizationMapper.toEntity(organizationDto);
            organizationRepository.save(organization);
    }


    @Override
    public void delOrganization(String id) {
        Organization organization = organizationRepository.findOrganizationById(id);
        organization.setDelete(1);
        organizationRepository.save(organization);
    }

    @Override
    public void delOrganizations (List<String> ids) { }

    @Override
    public JSONArray getOrgTree() {

        JSONArray result = new JSONArray(); // 最终返回
        // 虚拟顶层菜单
//        JSONObject virtualTop = new JSONObject();
//        virtualTop.put(MENU_TITLE,"组织树");
//        virtualTop.put(MENU_KEY,"");
//        virtualTop.put(MENU_VALUE,"");

        List<Organization> organizations =  organizationRepository.findOrganizationsByDeleteAndParentOrg(0,null);

        JSONArray arr = new JSONArray();
        for(Organization organization : organizations){
            JSONObject object = recursiveOrg(organization);
            arr.add(object);
        }
//        virtualTop.put(MENU_CHILDREN,arr);
//        result.add(virtualTop);
        return arr;


    }


    public JSONObject recursiveOrg(Organization organization){
        JSONObject object = new JSONObject();
        object.put(MENU_TITLE,organization.getOrgName());
        object.put(MENU_KEY,organization.getId());
        object.put(MENU_VALUE, organization.getId());
//        object.put("spread",false);
        if(organization.getChildOrgs().size()>0){
            JSONArray children = new JSONArray();
            for(Organization child : organization.getChildOrgs()){
                JSONObject obj = recursiveOrg(child);
                children.add(obj);
            }
            object.put(MENU_CHILDREN,children);
        }
        return object;
    }
}